<template>
  <a-modal
    v-model:open="modalVisible"
    :footer="null"
    width="80%"
    style="margin-top: -5rem;"
    wrap-class-name="online-preview-modal"
    @cancel="closePreview"
  >
    <div v-if="previewLoading" class="loading-container">
      <a-spin size="large" />
      <p>正在加载预览...</p>
    </div>
    <div v-else-if="previewFailed" class="loading-container">
      <a-result status="error" title="预览失败" :sub-title="errorMessage || '获取预览文件失败，请稍后重试'">
        <template #extra>
          <a-button type="primary" @click="retryPreview">重试</a-button>
        </template>
      </a-result>
    </div>
    <div
      v-show="!previewLoading && !previewFailed"
      :id="containerId"
      ref="luckysheetContainer"
      :style="{
        margin: '0px',
        padding: '0px',
        width: '100%',
        height: '46vw',
      }"
    />
  </a-modal>
</template>

<script setup lang="ts">
import { ref, onBeforeUnmount, watch, nextTick } from 'vue';
import { Modal, Spin, Result, Button } from 'ant-design-vue';
import * as LuckyExcel from 'luckyexcel';

const AMModal = Modal;
const ASpin = Spin;
const AResult = Result;
const AButton = Button;

// 为每个实例生成唯一的容器ID
const containerId = `luckysheet-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

// 定义组件属性
const props = defineProps<{
  visible: boolean;
  fileUrl: string;
  fileName: string;
}>();

// 定义事件发射
const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void;
  (e: 'close'): void;
  (e: 'retry'): void;
}>();

// 响应式数据
const modalVisible = ref(false);
const previewLoading = ref(false);
const previewFailed = ref(false);
const errorMessage = ref('');
const luckysheetContainer = ref<HTMLDivElement | null>(null);
let luckysheetInstance: any = null;
let currentFileUrl = ''; // 记录当前加载的文件URL，防止重复加载

// 监听visible属性变化
watch(
  () => props.visible,
  (newVal) => {
    modalVisible.value = newVal;
    if (newVal && props.fileUrl) {
      nextTick(() => {
        initPreview();
      });
    } else if (!newVal) {
      // 重置状态
      previewFailed.value = false;
      errorMessage.value = '';
    }
  },
  { immediate: true }
);

// 监听fileUrl属性变化
watch(
  () => props.fileUrl,
  (newVal) => {
    if (newVal && modalVisible.value) {
      // 总是重新加载，即使URL相同，因为可能是一个新的Blob对象
      nextTick(() => {
        initPreview();
      });
    }
  }
);

// 检测并处理自引用公式
const processSelfReferenceFormulas = (exportJson: any) => {
  if (!exportJson || !exportJson.sheets) return exportJson;
  console.log('正在处理自引用公式...', exportJson);
  exportJson.sheets.forEach((sheet: any) => {
    if (sheet.celldata) {
      sheet.celldata.forEach((cell: any) => {
        if (cell.v && cell.v.f) {
          // 获取单元格坐标
          const cellCoordinate = `${String.fromCharCode(65 + cell.c)}${cell.r + 1}`;

          // 检查公式是否引用了自身
          const formula = cell.v.f;
          const selfReferencePattern = new RegExp(`\\b${cellCoordinate}\\b`, 'i');

          if (selfReferencePattern.test(formula)) {
            // 如果发现自引用，移除公式并保留计算结果（如果有）
            console.warn(`发现自引用公式在单元格 ${cellCoordinate}: ${formula}`);
            delete cell.v.f; // 移除公式

            // 如果有计算结果，保留结果作为静态值
            if (cell.v.v !== undefined) {
              // 保持现有值
            } else if (cell.v.m !== undefined) {
              // 如果没有v但有m，使用m作为值
              cell.v.v = cell.v.m;
            }
          }
        }
      });
    }
  });

  return exportJson;
};

// 初始化预览
const initPreview = () => {
  if (!props.fileUrl) {
    console.error('缺少文件URL参数');
    showPreviewError('缺少文件URL参数');
    return;
  }

  // 如果URL没有变化，则不重新加载
  if (currentFileUrl === props.fileUrl) {
    return;
  }

  previewLoading.value = true;
  previewFailed.value = false;
  errorMessage.value = '';
  currentFileUrl = props.fileUrl;

  // 销毁已有的luckysheet实例
  destroyLuckysheet();

  // 使用LuckyExcel转换Excel文件并用Luckysheet展示
  // @ts-ignore
  LuckyExcel.transformExcelToLuckyByUrl(props.fileUrl, props.fileName, (exportJson: any) => {
    // 检查组件是否仍然处于打开状态
    if (!modalVisible.value) {
      previewLoading.value = false;
      return;
    }

    if (!exportJson || exportJson.sheets == null || exportJson.sheets.length === 0) {
      console.error('Excel解析失败');
      showPreviewError('Excel解析失败');
      return;
    }

    // 处理自引用公式问题
    const processedJson = processSelfReferenceFormulas(exportJson);
    console.log('正在加载Excel文件...', processedJson);

    // 确保DOM更新完成后再初始化Luckysheet
    nextTick(() => {
      // 延迟初始化Luckysheet，确保容器已渲染
      setTimeout(() => {
        // 再次检查组件是否仍然处于打开状态
        if (!modalVisible.value) {
          previewLoading.value = false;
          return;
        }

        // @ts-ignore
        luckysheetInstance = window.luckysheet.create({
          container: containerId,
          data: processedJson.sheets,
          title: props.fileName,
          userInfo: processedJson.info?.creator,
          showtoolbar: false,
          showinfobar: false,
          showstatisticBar: false,
          sheetBottomConfig: false,
          allowEdit: false,
          enableAddRow: false,
          enableAddCol: false,
          sheetFormulaBar: false,
          enableAddBackTop: false,
          showsheetbar: true,
          lang: 'zh', // 设置界面语言为中文
          // 禁用所有警告弹窗
          alert: {
            enable: false
          },
          // 公式计算相关配置
          calcChain: true,
          calcArray: true,
          forceCalculation: true,
          // 工作表选项
          showsheetbarConfig: {
            add: false,
            menu: false
          },
        });

        previewLoading.value = false;
      }, 100);
    });
  });
};

// 销毁Luckysheet实例
const destroyLuckysheet = () => {
  if (luckysheetInstance && luckysheetInstance.destroy) {
    try {
      luckysheetInstance.destroy();
    } catch (e) {
      console.warn('销毁Luckysheet实例时出错:', e);
    }
    luckysheetInstance = null;
  }

  // 清空容器内容
  if (luckysheetContainer.value) {
    luckysheetContainer.value.innerHTML = '';
  }
};

// 显示预览错误
const showPreviewError = (message: string) => {
  previewLoading.value = false;
  previewFailed.value = true;
  errorMessage.value = message;
};

// 重试预览
const retryPreview = () => {
  // 重置当前文件URL以便重新加载
  currentFileUrl = '';
  emit('retry');
};

// 关闭预览
const closePreview = () => {
  modalVisible.value = false;
  emit('update:visible', false);
  emit('close');
  // 重置状态
  previewFailed.value = false;
  errorMessage.value = '';
  currentFileUrl = '';
  // 销毁Luckysheet实例
  destroyLuckysheet();
};

// 组件卸载前清理
onBeforeUnmount(() => {
  // 销毁Luckysheet实例
  destroyLuckysheet();
  // 清空当前文件URL引用
  currentFileUrl = '';
});

// 暴露方法给父组件
defineExpose({
  closePreview
});
</script>

<style scoped>
.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 600px;
}

.loading-container p {
  margin-top: 16px;
  font-size: 14px;
  color: #666;
}
</style>
